/**
 * 图片压缩工具类
 * 使用 browser-image-compression 库进行高质量压缩
 */

import imageCompression from 'browser-image-compression'

export interface CompressionOptions {
  maxWidth?: number      // 最大宽度
  maxHeight?: number     // 最大高度
  quality?: number       // 压缩质量 (0.1 - 1.0)
  maxSizeMB?: number     // 最大文件大小 (MB)
  useWebWorker?: boolean // 是否使用Web Worker
  fileType?: string      // 输出文件类型
}

export interface CompressionResult {
  file: File
  originalSize: number
  compressedSize: number
  compressionRatio: number
  width?: number
  height?: number
}

const DEFAULT_OPTIONS: CompressionOptions = {
  maxWidth: 1920,        // 最大宽度1920px
  maxHeight: 1920,       // 最大高度1920px
  quality: 0.85,         // 85%质量，平衡质量和大小
  maxSizeMB: 1,          // 1MB
  useWebWorker: true,    // 使用Web Worker提高性能
  fileType: 'image/jpeg' // 输出格式
}

/**
 * 压缩图片
 * @param file 原始图片文件
 * @param options 压缩选项
 * @returns Promise<CompressionResult>
 */
export async function compressImage(
  file: File,
  options: CompressionOptions = {}
): Promise<CompressionResult> {
  const opts = { ...DEFAULT_OPTIONS, ...options }

  try {
    // 检查文件类型
    if (!file.type.startsWith('image/')) {
      throw new Error('不是有效的图片文件')
    }

    // 记录原始大小
    const originalSize = file.size

    // 使用 browser-image-compression 压缩
    const compressedFile = await imageCompression(file, {
      maxWidthOrHeight: Math.max(opts.maxWidth || 1920, opts.maxHeight || 1920),
      useWebWorker: opts.useWebWorker,
      maxSizeMB: opts.maxSizeMB,
      fileType: opts.fileType as any
    })

    // 计算压缩比例
    const compressionRatio = originalSize > 0
      ? ((originalSize - compressedFile.size) / originalSize) * 100
      : 0

    return {
      file: compressedFile,
      originalSize,
      compressedSize: compressedFile.size,
      compressionRatio,
      width: opts.maxWidth,
      height: opts.maxHeight
    }
  } catch (error) {
    console.error('图片压缩失败:', error)
    throw error
  }
}

/**
 * 智能压缩 - 根据文件大小自动调整压缩参数
 */
export async function smartCompress(file: File): Promise<CompressionResult> {
  const originalSize = file.size
  const maxSize = 1024 * 1024 // 1MB

  // 如果文件已经小于1MB，不需要压缩
  if (originalSize <= maxSize) {
    return {
      file,
      originalSize,
      compressedSize: originalSize,
      compressionRatio: 0
    }
  }

  // 根据文件大小调整压缩参数
  let quality = 0.85
  let maxWidth = 1920
  let maxHeight = 1920
  let maxSizeMB = 1

  if (originalSize > 10 * 1024 * 1024) { // 大于10MB
    quality = 0.7
    maxWidth = 1400
    maxHeight = 1400
    maxSizeMB = 0.8
  } else if (originalSize > 5 * 1024 * 1024) { // 大于5MB
    quality = 0.75
    maxWidth = 1600
    maxHeight = 1600
    maxSizeMB = 0.9
  } else if (originalSize > 3 * 1024 * 1024) { // 大于3MB
    quality = 0.8
    maxWidth = 1800
    maxHeight = 1800
    maxSizeMB = 0.95
  }

  return compressImage(file, {
    quality,
    maxWidth,
    maxHeight,
    maxSizeMB,
    fileType: 'image/jpeg'
  })
}

/**
 * 批量压缩图片
 */
export async function compressImages(
  files: File[],
  options: CompressionOptions = {}
): Promise<CompressionResult[]> {
  const results: CompressionResult[] = []

  for (const file of files) {
    try {
      const result = await compressImage(file, options)
      results.push(result)
    } catch (error) {
      console.error(`压缩文件 ${file.name} 失败:`, error)
      // 如果压缩失败，返回原文件
      results.push({
        file,
        originalSize: file.size,
        compressedSize: file.size,
        compressionRatio: 0
      })
    }
  }

  return results
}

/**
 * 检查是否需要压缩
 */
export function needsCompression(file: File, maxSizeMB: number = 1): boolean {
  return file.size > maxSizeMB * 1024 * 1024
}

/**
 * 获取文件大小的人类可读格式
 */
export function formatFileSize(bytes: number): string {
  if (bytes === 0) return '0 Bytes'

  const k = 1024
  const sizes = ['Bytes', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))

  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}
